suppressPackageStartupMessages(
{
package_list <- c('plotly', 'maps', 'foreach','RColorBrewer', 'dplyr', 'stringr', 'sqldf', 'magrittr','webshot')
non_installed <- package_list[!(package_list %in% installed.packages()[,"Package"])]
if(length(non_installed)) install.packages(non_installed)
library('plotly')
library('maps')
library('foreach')
library('RColorBrewer')
library('dplyr')
library('stringr')
library('sqldf')
library('magrittr')
library('webshot')
}
)
load required R packages
raw_data <- read.csv("police_shootings.csv", stringsAsFactors = F)
raw_data <- raw_data[complete.cases(raw_data),]
#Data Cleaning
colnames(raw_data) <- c("ID", "Name", "Date", "Manner_of_Death",
"Armed", "Age", "Gender", "Race",
"City", "State", "Mental_Illness",
"Attack", "Fleeing", "Body_Cam")
raw_data$Race[raw_data$Race == ""] <- "UNK"
raw_data_clean <- data.frame(raw_data)
raw_data_clean$Date <- as.Date(raw_data$Date)
raw_data_clean$Mental_Illness <- ifelse(raw_data$Mental_Illness == "True", T, F)
raw_data_clean$Attack <- ifelse(raw_data$Attack == "attack", T, F)
raw_data_clean$Armed <- as.logical(ifelse(raw_data$Armed %in% c("unarmed","undetermined"), F, T))
raw_data_clean$Fleeing <- as.factor(raw_data$Fleeing)
raw_data_nonViolent <- sqldf("SELECT *
FROM raw_data_clean
WHERE Attack")
raw_data_plotly <- plot_ly(raw_data_nonViolent) %>%
add_markers(x = ~Date, y = ~Age, color = ~Race,
text = ~paste("</br>Name: ", Name,
"</br>Race: ", Race,
"</br>Gender: ", Gender)) %>%
layout(title = "Date and Age of Victims Killed By Policing in Nonviolent Encounters")
suppressWarnings({raw_data_plotly})
Raw Set of Police Shooting Data
cityShootings <- sqldf("Select COUNT(City) As Shootings, LOWER(City) As City,
State, Race
From raw_data_nonViolent
Group By City
Order By State")
#clean up city names for data join on city and state
cityLoc <- us.cities
cityLoc$name <- foreach(x = 1:length(cityLoc$name), .combine = c) %do%
tolower(rawToChar(charToRaw(cityLoc$name[x])[1:(length(charToRaw(cityLoc$name[x]))-3)]))
colnames(cityLoc) <- c("City", "State", "Population", "Latitude", "Longitude", "Capital")
cityShootingLoc <- sqldf("Select cityShootings.*, Population/cityShootings.Shootings As KillingPer,
Population, Latitude, Longitude
From cityShootings Inner Join cityLoc
On cityLoc.City == cityShootings.City And cityLoc.State == cityShootings.State
Order By cityShootings.State, cityShootings.City")
cityShooting_geo_plotly <- ggplot2::map_data("state") %>%
plot_ly(x = ~long, y = ~lat)%>%
group_by(group) %>%
add_polygons(name = "USA", hoverinfo = "none") %>%
add_markers(name = "Shootings", data = cityShootingLoc[ifelse(
cityShootingLoc$State %in% c('HI','AK'), FALSE, TRUE),],
x = ~Longitude, y = ~Latitude,
color = ~KillingPer, colors = "Spectral",
size = ~Shootings,
text = ~paste("</br>City: ", City,
"</br>State: ", State,
"</br>Population: ", Population,
"</br>Shootings: ", Shootings),
hoverinfo = text) %>%
layout(title = "Police Shootings of Non-Violent Civilians 2015 - 2017",
xaxis = list(title = "Longitude"),
yaxis = list(title = "Latitude"))
cityShooting_geo_plotly
#cityShooting_geo_gg
ByRaceCount <- sqldf("SELECT race As Race, COUNT( race ) As Number
FROM raw_data_nonViolent
GROUP BY race")
#data on race in the US: https://www.census.gov/quickfacts/fact/table/US/PST045216
ByRaceCount$RacePCT_2016 <- c( "A" = 0.057,
"B" = 0.133,
"H" = 0.178,
"N" = 0.013,
"O" = 0.002,
"UNK" = 0.004,
"W" = 0.613)
ByRaceCount$Expected_Number <- ceiling(sum(ByRaceCount$Number) * ByRaceCount$RacePCT_2016)
ByRaceCount_plotly <- plot_ly() %>%
add_pie(data = ByRaceCount[c("Race", "Number")],
name = "Actual Result", labels =~Race, values = ~Number,
domain = list(x = c(0, 0.4), y = c(0.3, 0.7))) %>%
add_pie(data = ByRaceCount[c("Race", "Expected_Number")],
name = "Expected Result", labels = ~Race, values = ~Expected_Number,
domain = list(x = c(0.6, 1), y = c(0.3, 0.7))) %>%
layout(title = "Police Shootings of Non-Violent Civilians By Race 2015-2017
</br> Actual vs. By Representation in Population
</br>(Using 2016 Population Percentages)",
xaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = FALSE),
yaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = FALSE))
ByRaceCount_plotly
LS0tDQp0aXRsZTogIkZhdGFsIFBvbGljZSBTaG9vdGluZ3MsIDIwMTUtUHJlc2VudCINCmF1dGhvcjogIkR1bmNhbiBNY0tpbm5vbiINCm91dHB1dDogaHRtbF9kb2N1bWVudA0KLS0tDQojQ2l2aWxpYW5zIHNob3QgYW5kIGtpbGxlZCBieSBvbi1kdXR5IHBvbGljZSBvZmZpY2VycyBpbiBVbml0ZWQgU3RhdGVzDQojRnJvbSBMb2NhdGlvbjogaHR0cHM6Ly93d3cua2FnZ2xlLmNvbS93YXNoaW5ndG9ucG9zdC9wb2xpY2Utc2hvb3RpbmdzDQoNCg0KYGBge3IgbWVzc2FnZXMgPSBGLCB3YXJuaW5nID0gRn0NCnN1cHByZXNzUGFja2FnZVN0YXJ0dXBNZXNzYWdlcygNCiAgew0KICAgIHBhY2thZ2VfbGlzdCA8LSBjKCdwbG90bHknLCAnbWFwcycsICdmb3JlYWNoJywnUkNvbG9yQnJld2VyJywgJ2RwbHlyJywgJ3N0cmluZ3InLCAnc3FsZGYnLCAnbWFncml0dHInLCd3ZWJzaG90JykNCiAgICBub25faW5zdGFsbGVkIDwtIHBhY2thZ2VfbGlzdFshKHBhY2thZ2VfbGlzdCAlaW4lIGluc3RhbGxlZC5wYWNrYWdlcygpWywiUGFja2FnZSJdKV0NCiAgICBpZihsZW5ndGgobm9uX2luc3RhbGxlZCkpIGluc3RhbGwucGFja2FnZXMobm9uX2luc3RhbGxlZCkNCiAgICBsaWJyYXJ5KCdwbG90bHknKQ0KICAgIGxpYnJhcnkoJ21hcHMnKQ0KICAgIGxpYnJhcnkoJ2ZvcmVhY2gnKQ0KICAgIGxpYnJhcnkoJ1JDb2xvckJyZXdlcicpDQogICAgbGlicmFyeSgnZHBseXInKQ0KICAgIGxpYnJhcnkoJ3N0cmluZ3InKQ0KICAgIGxpYnJhcnkoJ3NxbGRmJykNCiAgICBsaWJyYXJ5KCdtYWdyaXR0cicpDQogICAgbGlicmFyeSgnd2Vic2hvdCcpDQogIH0NCikNCg0KYGBgDQpsb2FkIHJlcXVpcmVkIFIgcGFja2FnZXMNCg0KYGBge3IgbWVzc2FnZSA9IEYsIHdhcm5pbmcgPSBGfQ0KcmF3X2RhdGEgPC0gcmVhZC5jc3YoInBvbGljZV9zaG9vdGluZ3MuY3N2Iiwgc3RyaW5nc0FzRmFjdG9ycyA9IEYpDQpyYXdfZGF0YSA8LSByYXdfZGF0YVtjb21wbGV0ZS5jYXNlcyhyYXdfZGF0YSksXQ0KDQojRGF0YSBDbGVhbmluZw0KY29sbmFtZXMocmF3X2RhdGEpIDwtIGMoIklEIiwgIk5hbWUiLCAiRGF0ZSIsICJNYW5uZXJfb2ZfRGVhdGgiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQXJtZWQiLCAiQWdlIiwgIkdlbmRlciIsICJSYWNlIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNpdHkiLCAiU3RhdGUiLCAiTWVudGFsX0lsbG5lc3MiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQXR0YWNrIiwgIkZsZWVpbmciLCAiQm9keV9DYW0iKQ0KDQoNCnJhd19kYXRhJFJhY2VbcmF3X2RhdGEkUmFjZSA9PSAiIl0gPC0gIlVOSyIgDQoNCnJhd19kYXRhX2NsZWFuIDwtIGRhdGEuZnJhbWUocmF3X2RhdGEpDQpyYXdfZGF0YV9jbGVhbiREYXRlIDwtIGFzLkRhdGUocmF3X2RhdGEkRGF0ZSkNCnJhd19kYXRhX2NsZWFuJE1lbnRhbF9JbGxuZXNzIDwtIGlmZWxzZShyYXdfZGF0YSRNZW50YWxfSWxsbmVzcyA9PSAiVHJ1ZSIsIFQsIEYpDQpyYXdfZGF0YV9jbGVhbiRBdHRhY2sgPC0gaWZlbHNlKHJhd19kYXRhJEF0dGFjayA9PSAiYXR0YWNrIiwgVCwgRikNCnJhd19kYXRhX2NsZWFuJEFybWVkIDwtIGFzLmxvZ2ljYWwoaWZlbHNlKHJhd19kYXRhJEFybWVkICVpbiUgYygidW5hcm1lZCIsInVuZGV0ZXJtaW5lZCIpLCBGLCBUKSkNCnJhd19kYXRhX2NsZWFuJEZsZWVpbmcgPC0gYXMuZmFjdG9yKHJhd19kYXRhJEZsZWVpbmcpDQoNCg0KcmF3X2RhdGFfbm9uVmlvbGVudCA8LSBzcWxkZigiU0VMRUNUICogDQogICAgICAgICAgICAgICAgICAgICAgIEZST00gcmF3X2RhdGFfY2xlYW4NCiAgICAgICAgICAgICAgICAgICAgICAgV0hFUkUgQXR0YWNrIikNCg0KcmF3X2RhdGFfcGxvdGx5IDwtIHBsb3RfbHkocmF3X2RhdGFfbm9uVmlvbGVudCkgJT4lDQogICAgICAgICAgICAgICAgICAgYWRkX21hcmtlcnMoeCA9IH5EYXRlLCB5ID0gfkFnZSwgY29sb3IgPSB+UmFjZSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXh0ID0gfnBhc3RlKCI8L2JyPk5hbWU6ICIsIE5hbWUsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiPC9icj5SYWNlOiAiLCBSYWNlLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjwvYnI+R2VuZGVyOiAiLCBHZW5kZXIpKSAlPiUNCiAgICAgICAgICAgICAgICAgICBsYXlvdXQodGl0bGUgPSAiRGF0ZSBhbmQgQWdlIG9mIFZpY3RpbXMgS2lsbGVkIEJ5IFBvbGljaW5nIGluIE5vbnZpb2xlbnQgRW5jb3VudGVycyIpDQoNCnN1cHByZXNzV2FybmluZ3Moe3Jhd19kYXRhX3Bsb3RseX0pDQoNCmBgYA0KUmF3IFNldCBvZiBQb2xpY2UgU2hvb3RpbmcgRGF0YQ0KYGBge3IgbWVzc2FnZSA9IEYsIHdhcm5pbmcgPSBGfQ0KY2l0eVNob290aW5ncyA8LSBzcWxkZigiU2VsZWN0IENPVU5UKENpdHkpIEFzIFNob290aW5ncywgTE9XRVIoQ2l0eSkgQXMgQ2l0eSwgDQogICAgICAgICAgICAgICAgICAgICAgICBTdGF0ZSwgUmFjZQ0KICAgICAgICAgICAgICAgICAgICAgICAgIEZyb20gcmF3X2RhdGFfbm9uVmlvbGVudA0KICAgICAgICAgICAgICAgICAgICAgICAgIEdyb3VwIEJ5IENpdHkNCiAgICAgICAgICAgICAgICAgICAgICAgICBPcmRlciBCeSBTdGF0ZSIpDQoNCiNjbGVhbiB1cCBjaXR5IG5hbWVzIGZvciBkYXRhIGpvaW4gb24gY2l0eSBhbmQgc3RhdGUNCmNpdHlMb2MgPC0gdXMuY2l0aWVzDQpjaXR5TG9jJG5hbWUgPC0gZm9yZWFjaCh4ID0gMTpsZW5ndGgoY2l0eUxvYyRuYW1lKSwgLmNvbWJpbmUgPSBjKSAlZG8lICAgICAgDQogICAgICAgICAgICAgICAgICAgICAgICB0b2xvd2VyKHJhd1RvQ2hhcihjaGFyVG9SYXcoY2l0eUxvYyRuYW1lW3hdKVsxOihsZW5ndGgoY2hhclRvUmF3KGNpdHlMb2MkbmFtZVt4XSkpLTMpXSkpDQoNCmNvbG5hbWVzKGNpdHlMb2MpIDwtIGMoIkNpdHkiLCAiU3RhdGUiLCAiUG9wdWxhdGlvbiIsICJMYXRpdHVkZSIsICJMb25naXR1ZGUiLCAiQ2FwaXRhbCIpDQoNCmNpdHlTaG9vdGluZ0xvYyA8LSBzcWxkZigiU2VsZWN0IGNpdHlTaG9vdGluZ3MuKiwgUG9wdWxhdGlvbi9jaXR5U2hvb3RpbmdzLlNob290aW5ncyBBcyBLaWxsaW5nUGVyLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgUG9wdWxhdGlvbiwgTGF0aXR1ZGUsIExvbmdpdHVkZQ0KICAgICAgICAgICAgICAgICAgICAgICAgICBGcm9tIGNpdHlTaG9vdGluZ3MgSW5uZXIgSm9pbiBjaXR5TG9jIA0KICAgICAgICAgICAgICAgICAgICAgICAgICBPbiBjaXR5TG9jLkNpdHkgPT0gY2l0eVNob290aW5ncy5DaXR5IEFuZCBjaXR5TG9jLlN0YXRlID09IGNpdHlTaG9vdGluZ3MuU3RhdGUNCiAgICAgICAgICAgICAgICAgICAgICAgICAgT3JkZXIgQnkgY2l0eVNob290aW5ncy5TdGF0ZSwgY2l0eVNob290aW5ncy5DaXR5IikNCg0KDQoNCg0KY2l0eVNob290aW5nX2dlb19wbG90bHkgPC0gZ2dwbG90Mjo6bWFwX2RhdGEoInN0YXRlIikgJT4lDQogICAgICAgICAgICAgICAgICAgICAgICAgICBwbG90X2x5KHggPSB+bG9uZywgeSA9IH5sYXQpJT4lDQogICAgICAgICAgICAgICAgICAgICAgICAgICBncm91cF9ieShncm91cCkgJT4lDQogICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRfcG9seWdvbnMobmFtZSA9ICJVU0EiLCBob3ZlcmluZm8gPSAibm9uZSIpICU+JQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkX21hcmtlcnMobmFtZSA9ICJTaG9vdGluZ3MiLCBkYXRhID0gY2l0eVNob290aW5nTG9jW2lmZWxzZSgNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2l0eVNob290aW5nTG9jJFN0YXRlICVpbiUgYygnSEknLCdBSycpLCBGQUxTRSwgVFJVRSksXSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4ID0gfkxvbmdpdHVkZSwgeSA9IH5MYXRpdHVkZSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvciA9IH5LaWxsaW5nUGVyLCBjb2xvcnMgPSAiU3BlY3RyYWwiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZSA9IH5TaG9vdGluZ3MsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXh0ID0gfnBhc3RlKCI8L2JyPkNpdHk6ICIsIENpdHksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICI8L2JyPlN0YXRlOiAiLCBTdGF0ZSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjwvYnI+UG9wdWxhdGlvbjogIiwgUG9wdWxhdGlvbiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjwvYnI+U2hvb3RpbmdzOiAiLCBTaG9vdGluZ3MpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaG92ZXJpbmZvID0gdGV4dCkgJT4lDQogICAgICAgICAgICAgICAgICAgICAgICAgIGxheW91dCh0aXRsZSA9ICJQb2xpY2UgU2hvb3RpbmdzIG9mIE5vbi1WaW9sZW50IENpdmlsaWFucyAyMDE1IC0gMjAxNyIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeGF4aXMgPSBsaXN0KHRpdGxlID0gIkxvbmdpdHVkZSIpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeWF4aXMgPSBsaXN0KHRpdGxlID0gIkxhdGl0dWRlIikpDQoNCg0KY2l0eVNob290aW5nX2dlb19wbG90bHkNCiNjaXR5U2hvb3RpbmdfZ2VvX2dnDQpgYGANCg0KYGBge3J9DQpCeVJhY2VDb3VudCA8LSBzcWxkZigiU0VMRUNUIHJhY2UgQXMgUmFjZSwgQ09VTlQoIHJhY2UgKSBBcyBOdW1iZXINCiAgICAgICAgICAgICAgICAgICAgICBGUk9NIHJhd19kYXRhX25vblZpb2xlbnQNCiAgICAgICAgICAgICAgICAgICAgICBHUk9VUCBCWSByYWNlIikNCg0KI2RhdGEgb24gcmFjZSBpbiB0aGUgVVM6IGh0dHBzOi8vd3d3LmNlbnN1cy5nb3YvcXVpY2tmYWN0cy9mYWN0L3RhYmxlL1VTL1BTVDA0NTIxNg0KQnlSYWNlQ291bnQkUmFjZVBDVF8yMDE2IDwtICBjKCAiQSIgPSAwLjA1NywgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJCIiA9IDAuMTMzLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkgiID0gMC4xNzgsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTiIgPSAwLjAxMywgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJPIiA9IDAuMDAyLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVU5LIiA9IDAuMDA0LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVyIgPSAwLjYxMykNCg0KQnlSYWNlQ291bnQkRXhwZWN0ZWRfTnVtYmVyIDwtIGNlaWxpbmcoc3VtKEJ5UmFjZUNvdW50JE51bWJlcikgKiBCeVJhY2VDb3VudCRSYWNlUENUXzIwMTYpDQoNCkJ5UmFjZUNvdW50X3Bsb3RseSA8LSBwbG90X2x5KCkgJT4lIA0KICAgICAgICAgICAgICAgICAgICAgIGFkZF9waWUoZGF0YSA9IEJ5UmFjZUNvdW50W2MoIlJhY2UiLCAiTnVtYmVyIildLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUgPSAiQWN0dWFsIFJlc3VsdCIsIGxhYmVscyA9flJhY2UsIHZhbHVlcyA9IH5OdW1iZXIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb21haW4gPSBsaXN0KHggPSBjKDAsIDAuNCksIHkgPSBjKDAuMywgMC43KSkpICU+JSANCiAgICAgICAgICAgICAgICAgICAgICBhZGRfcGllKGRhdGEgPSBCeVJhY2VDb3VudFtjKCJSYWNlIiwgIkV4cGVjdGVkX051bWJlciIpXSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUgPSAiRXhwZWN0ZWQgUmVzdWx0IiwgbGFiZWxzID0gflJhY2UsIHZhbHVlcyA9IH5FeHBlY3RlZF9OdW1iZXIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb21haW4gPSBsaXN0KHggPSBjKDAuNiwgMSksIHkgPSBjKDAuMywgMC43KSkpICU+JQ0KICAgICAgICAgICAgICAgICAgICAgIGxheW91dCh0aXRsZSA9ICJQb2xpY2UgU2hvb3RpbmdzIG9mIE5vbi1WaW9sZW50IENpdmlsaWFucyBCeSBSYWNlIDIwMTUtMjAxNyANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9icj4gQWN0dWFsIHZzLiBCeSBSZXByZXNlbnRhdGlvbiBpbiBQb3B1bGF0aW9uDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYnI+KFVzaW5nIDIwMTYgUG9wdWxhdGlvbiBQZXJjZW50YWdlcykiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4YXhpcyA9IGxpc3Qoc2hvd2dyaWQgPSBGQUxTRSwgemVyb2xpbmUgPSBGQUxTRSwgc2hvd3RpY2tsYWJlbHMgPSBGQUxTRSksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHlheGlzID0gbGlzdChzaG93Z3JpZCA9IEZBTFNFLCB6ZXJvbGluZSA9IEZBTFNFLCBzaG93dGlja2xhYmVscyA9IEZBTFNFKSkNCg0KQnlSYWNlQ291bnRfcGxvdGx5DQpgYGANCg0KDQoNCg0KDQoNCg0KDQo=